import * as bodyParser from "body-parser";
import * as cookieParser from "cookie-parser";
import * as express from "express";
import * as logger from "morgan";
import * as path from "path";

import * as createError from 'http-errors';
import * as helmet from 'helmet';//安全应用 
import * as compression from 'compression';//压缩
import * as csrf from 'csurf';//防止csurf攻击 
import * as session from 'express-session';
import * as errorHandler from "errorhandler";

import { IndexRoute } from "./routes/index"; 
import { LOG } from "./Controller/LOG";  
import { WSService } from "./Controller/WSService"; 
import { CONFIG } from "./config"; 

/**
 * The server.
 *
 * @class Server
 */
export class Server {

  public app: express.Application;

  /**
   * Bootstrap the application.
   *
   * @class Server
   * @method bootstrap
   * @static
   * @return {ng.auto.IInjectorService} Returns the newly created injector for this app.
   */
  public static bootstrap(): Server {
    return new Server();
  }

  /**
   * Constructor.
   *
   * @class Server
   * @constructor
   */
  constructor() {
    //create expressjs application
    this.app = express();

    //configure application
    this.config();

    //add routes
    this.routes();

    //add api
    this.api();
  }

  /**
   * Create REST API routes
   *
   * @class Server
   * @method api
   */
  public api() {
    //empty for now

 

  }

  public wsService(server)
  {
     new WSService(server);
  }

  /**
   * Configure application
   *
   * @class Server
   * @method config
   */
  public config() {
    //add static paths
    this.app.use(express.static(path.join(__dirname, "public")));

    //configure pug
    console.log(__dirname);
    this.app.set("views", path.join(__dirname, "views"));
    //this.app.set("view engine", "pug");
    this.app.set("view engine", "ejs");
    // load config
    new CONFIG();
    //  log4js
    new LOG().USE(this.app); 
    //mount logger
    this.app.use(logger("dev"));

    //mount json form parser
    this.app.use(bodyParser.json());

    //mount query string parser
    this.app.use(bodyParser.urlencoded({
      extended: true
    }));

    //mount cookie parser middleware
    this.app.use(cookieParser("SECRET_GOES_HERE"));

    // catch 404 and forward to error handler
    this.app.use(function(err: any, req: express.Request, res: express.Response, next: express.NextFunction) {
        err.status = 404;
        next(err);
    });

    //error handling
    this.app.use(errorHandler());

    this.app.use(helmet());
    this.app.use(compression());
    this.app.use(csrf({ cookie: true }));
    this.app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false}));

    // catch 404 and forward to error handler
    // this.app.use(function (req, res, next) {
    //   next(createError(404));
    // });
    // error handler
    // this.app.use(function (err, req, res, next) {
    //   // set locals, only providing error in development
    //   res.locals.message = err.message;
    //   res.locals.error = req.app.get('env') === 'development' ? err : {};

    //   // render the error page
    //   res.status(err.status || 500);
    //   res.send('error');
    // });
  }

  /**
   * Create and return Router.
   *
   * @class Server
   * @method routes
   * @return void
   */
  private routes() {
    let router: express.Router;
    router = express.Router();

    //IndexRoute
    IndexRoute.create(router);

    //use router middleware
    this.app.use(router);
  }

}
